/*
 * jaccardTest.c
 *
 *  Created on: May 3, 2009
 *      Author: sears
 */
#include "../m_tree/mTree.h"
#include "sparse.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>

static void castIntTo128BitArray(uint64_t in, struct uint128_t * out) {
	memset(out->buf, 0, 128/8);
	int i;
	for(i = 0; i < 64/8; i++) {
		out->buf[128/8-(i+1)] = in % 256;
		in /= 256;
	}
}

static int deltaEq(double a, double b) {
	return fabs(a-b) < 0.000001;
}

static uint64_t cast128bitArrayTo64BitInt(const struct uint128_t * in) {
	uint64_t ret = 0;
	int i = 0;
	for(i = 64/8; i > 0; i--) {
		ret *= 256;
		ret += in->buf[128/8-i];
	}
	return ret;
}

static void load_it(long count, /*long vector_len,*/ double vector_step) {
	long vector_len = 100;

	long i;
	long j;

	const char * store = "test.store";
	const char * store_fat = "test.store.fat";
	const char * mtree = "test.mTree";
	const char * mtree_fat = "test.mTree.fat";

	unlink(store);
	unlink(store_fat);
	unlink(mtree);
	unlink(mtree_fat);

	struct store * s = store_open_cached(store, store_fat, sizeof(struct uint128_vec),
					 ( 1024 * 1024 * 1024 )/ sizeof(struct uint128_vec),
					 ( 1024 * 1024 ) / sizeof(struct uint128_vec));

	struct mTree * m = mTree_open_cached(s, mtree, mtree_fat, 512 * 1024, jaccard_distance_sparse);


	for(i = 0; i < count; i++) {
		off_t off = store_new(s);
		struct uint128_vec * vec = store_read(s, off);
		vec->len = vector_len;

		long long cur = 0;
		for(j = 0; j < vector_len; j++) {
			cur += (1 + (rand() / (((double)RAND_MAX)/vector_step)));
			castIntTo128BitArray(cur, &vec->vals[j]);
		}
		store_write(s, off);
		store_release(s, off);
		mTree_insert(m, off);
	}

	mTree_close(m);
}

int main(int argc, char** argv) {
	struct uint128_t x;
	castIntTo128BitArray(1234567890, &x);
	assert(1234567890 == cast128bitArrayTo64BitInt(&x));

	struct uint128_t y;
	castIntTo128BitArray(1234567891, &y);
	assert(cmp_128bit(x,y)<0);
	assert(cmp_128bit(x,x)==0);

	struct uint128_vec xv, yv;
	xv.vals[0] = x; xv.len = 1;
	yv.vals[0] = y; yv.len = 1;

	assert(deltaEq(jaccard_distance_sparse(&xv,&yv),1.0));
	assert(deltaEq(jaccard_distance_sparse(&xv,&xv),0.0));

//	long vector_len = 1000;
	double vector_step = 5.0;
	long count = 100000;

	load_it(count, /*vector_len,*/ vector_step);

	return 0;
}
